package com.firexxx.study.visitor;

import org.objectweb.asm.commons.AdviceAdapter;

/**
 * @description: TODO
 * @throws:
 * @author: zhuangzhang2
 * @date: 2020/07/05 10:28
 */
public class TimeAdviceAdapter extends AdviceAdapter {

    private String key;
    private TimeMethodVisitor timeMethodVisitor;

    protected TimeAdviceAdapter(int api, TimeMethodVisitor methodVisitor, int access, String name, String descriptor, String key) {
        super(api, methodVisitor, access, name, descriptor);
        this.key = key;
        this.timeMethodVisitor = methodVisitor;
    }

    //方法进入时获取开始时间
    @Override
    public void onMethodEnter() {
        if (timeMethodVisitor.isTimeCostExist()) {
            System.out.println("发现需要计时的函数:" + key);

            mv.visitLdcInsn(key);
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "currentTimeMillis", "()J", false);
            mv.visitMethodInsn(INVOKESTATIC,
                    "com/firexxx/study/TimeCache",
                    "setStartTime",
                    "(Ljava/lang/String;J)V",
                    false);
        }
    }
    //方法退出时获取结束时间并计算执行时间
    @Override
    public void onMethodExit(int opcode) {
        if (timeMethodVisitor.isTimeCostExist()) {
            mv.visitLdcInsn(key);
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "currentTimeMillis", "()J", false);
            mv.visitMethodInsn(INVOKESTATIC,
                    "com/firexxx/study/TimeCache",
                    "setEndTime",
                    "(Ljava/lang/String;J)V",
                    false);
            mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
            mv.visitLdcInsn(key);
            mv.visitMethodInsn(INVOKESTATIC,
                    "com/firexxx/study/TimeCache",
                    "getCostTime",
                    "(Ljava/lang/String;)Ljava/lang/String;",
                    false);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
        }
    }

}